Instructions for Use:

0. Install hcextract and wobadecode in a /bin/ directory somewhere. This can be /bin, usr/bin, usr/local/bin, sw/bin, etc.; just anywhere in your PATH.

1. Create a folder and copy a HyperCard stack into it. Launch Terminal and cd to that folder. Let's assume the name of the stack is "Art Bits."

2. Execute this command:

hcextract "Art Bits" BMAP

This will extract all the card bitmaps from the stack and dump them in the current directory (the folder you created in step 1 if you've been following directions properly). They'll all be named BMAP #xxxx where xxxx is a number.

3. Let's say you want to look at BMAP #1209. First let's convert it to a format something other than HyperCard can understand:

wobadecode "BMAP #1209"

This will create another file named "BMAP #1209.rbit", with contains the now uncompressed card bitmap.

4. In GraphicConverter, select File > Open. In the Filter popup, select Raw. Navigate to the .rbit file and open it.

5. The RAW dialog will appear. Enter the value 32 in the Offset field. Enter the width of your stack (512 is the default for new stacks; you might want to check with Stack Info...) in the Width field. Click the Guess button. Click the Grayscale, 1 Bit, and Motorola radio buttons. Make sure "Black is $00" and "Import frames until end of file" are UNchecked. Click OK.

5.5. You should see the card bitmap on top and its mask on the bottom. :) If it looks screwed up, send the stack to me so I can figure out what went wrong.

6. Repeat steps 3-5.5 for other bitmaps you want to look at.

7. Repeat steps 1-6 for other stacks you want to look at.


About HCExtract:

The basic structure of HyperCard's file format is quite simple. It is composed of several individual "blocks" of data. Each block starts with an offset to the next block, the block type, the block ID number, and a filler word, then the ooey gooey data inside. It continues like this to the end of the file.

What HCExtract does is simply decompose a HyperCard stack into its individual blocks and write them out to files named with the block type and ID number. We can ask HCExtract to extract all of the blocks:

hcextract "Art Bits"

Or just blocks of a certain type:

hcextract "Art Bits" BMAP

Or one specific block:

hcextract "Art Bits" BMAP 1209

Since we're most interested in the card bitmaps, we only extracted all the BMAP blocks. If we wanted the cards themselves, we'd extract all the CARD blocks; or if we wanted report templates, we'd extract all the PRFT blocks.

We can also get HCExtract to tell us the types and ID numbers of all the blocks in the file:

hcextract "Art Bits" toc

(Notice it's lowercase 'toc', NOT uppercase 'TOC'; if we passed 'TOC', HCExtract would complain about 'TOC' not being a valid block type [block types are always 4 letters].)

The 'toc' function makes it look like there are two TAIL #-1 blocks in the file, but in fact this is just a bug in HCExtract.


About WOBADecode:

The format of the BMAP block itself is not so simple. It's certainly the card image, but it's compressed using a very crazy, very weird compression scheme invented by Bill Atkinson, the creator of HyperCard. It's completely unlike any other compression scheme we've ever seen, so we decided to call it WOBA, which stands for Wrath Of Bill Atkinson. :D

WOBADecode will take the data from the BMAP blocks extracted from the HyperCard stack and decompress them, generating a raw bitmap file as output.

The .rbit file generated by WOBADecode is actually generated by the writefile function of the picture class in picture.cpp. It has a 32-byte header containing a signature, a filler word, the width, the height, the depth, the mask depth, the bitmap length, and the mask length, followed by the bitmap data and the mask data. The signature is 0x12AAB175, which corresponds to the formal title I came up with for the format: RaaBits. :)

